﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using log4net;
using System.Diagnostics;
using System.IO;


namespace TumbaloSoft.Models
{
    public class GastoPresupuesto
    {
        private int idGastoPresupuesto;
        private String descripcion;
        private double monto;
        private int frecMeses;

        public int prFrecMeses
        {
            get { return frecMeses; }
            set { frecMeses = value; }
        }

        public double prMonto
        {
            get { return monto; }
            set { monto = value; }
        }

        public String prDescripcion
        {
            get { return descripcion; }
            set { descripcion = value; }
        }

        public int prIdGastoPresupuesto
        {
            get { return idGastoPresupuesto; }
            set { idGastoPresupuesto = value; }
        }

        public GastoPresupuesto(GastosComunes gastoComun)
        {
            descripcion = gastoComun.prTipoServicio.prDescripcion;
            monto = gastoComun.prMonto;
            frecMeses = 1;
        }
        public GastoPresupuesto(ContratoMantenimiento contrato)
        {
            descripcion = contrato.prDescripcion;
            monto = (double)contrato.prMonto;
            frecMeses = (int)contrato.prFrecuencia;
        }
        public GastoPresupuesto(string desc, double subtotal)
        {
            descripcion = desc;
            monto = subtotal;
            frecMeses = 1;
        }

    }

    public class CalculadorCuotaMes
    {
        private Edificio edificio;
        private List<GastoPresupuesto> gastos;
        private List<int> interiores;
        private List<DetalleCuota> detalles;
        private List<double> cuotas;
        private int tipocuota;
        private double montoextra;

        public List<DetalleCuota> prDetalles
        {
            get { return detalles; }
            set { detalles = value; }
        }

        public List<int> prInteriores
        {
            get { return interiores; }
            set { interiores = value; }
        }

        public List<double> prCuotas
        {
            get { return cuotas; }
            set { cuotas = value; }
        }

        public CalculadorCuotaMes(Edificio edif, List<GastoPresupuesto> gast, int tipo, int montoex)
        {
            edificio = edif;
            gastos = gast;
            tipocuota = tipo;
            cuotas = new List<double>();
            detalles = new List<DetalleCuota>();
            interiores = new List<int>();
            montoextra = montoex;

            for (int i = 0; i < edificio.prListaDepartamentos.Count; i++)
                interiores.Add(edificio.prListaDepartamentos[i].prNumeroDepartamento);

        }

        public void hallarCuota()
        {
            double totalmes = 0;
            double cuota;
            double factor;
            double sumaarea = 0;
            for (int i = 0; i < gastos.Count; i++)
            {
                totalmes += gastos[i].prMonto / gastos[i].prFrecMeses;
            }
            //ya tenemos el monto total en el mes a pagar

            if (tipocuota == 0) //si es 0 sera cuota fija
            {
                cuota = totalmes / interiores.Count + montoextra;
                for (int i = 0; i < interiores.Count; i++) cuotas.Add(cuota);
                for (int i = 0; i < interiores.Count; i++)
                {
                    for (int j = 0; j < gastos.Count; j++)
                    {
                        detalles.Add(new DetalleCuota(i, gastos[j].prDescripcion, (gastos[j].prMonto / gastos[j].prFrecMeses) / interiores.Count));
                    }
                }

            }
            if (tipocuota == 1) // si es 1 sera proporcional al area
            {
                sumaarea = hallarSumaArea();
                factor = totalmes / sumaarea; //hallamos cuantos soles x m2 se debe pagar
                for (int i = 0; i < edificio.prListaDepartamentos.Count; i++)
                {
                    cuota = edificio.prListaDepartamentos[i].prAreaTotal * factor + montoextra;
                    cuotas.Add(cuota);
                }
                for (int i = 0; i < interiores.Count; i++)
                {
                    double tasaAsignacion = edificio.prListaDepartamentos[i].prAreaTotal / sumaarea;
                    for (int j = 0; j < gastos.Count; j++)
                    {
                        detalles.Add(new DetalleCuota(i, gastos[j].prDescripcion, (gastos[j].prMonto / gastos[j].prFrecMeses) * tasaAsignacion));
                    }
                }

            }

            //en cuotas ya se tiene la cuota por cada interior en el mismo orden q en los arreglos de la clase departamento
        }

        private double hallarSumaArea()
        {
            double suma = 0;
            for (int i = 0; i < edificio.prListaDepartamentos.Count; i++)
                suma += edificio.prListaDepartamentos[i].prAreaTotal;
            return suma;
        }
    }

    public class Logger
    {
        ILog log = log4net.LogManager.GetLogger("Logging");
        private static volatile Logger _current = null;
        private static object syncRoot = new object();
        private Logger()
        { }
        public static Logger Current
        {
            get
            {
                if (_current == null)
                {
                    lock (syncRoot)
                    {
                        if (_current == null)
                        {
                            _current = new Logger();
                        }
                    }
                }
                return _current;
            }
        }
        public void Debug(string message)
        {
            if (this.log.IsDebugEnabled)
                this.log.Debug("[" + DateTime.Now.ToString() + "] " + ExtractInfo(message));
        }
        public void Info(string message)
        {
            if (this.log.IsInfoEnabled)
                this.log.Info("[" + DateTime.Now.ToString() + "] " + ExtractInfo(message));
        }
        public void Error(string message, System.Exception e)
        {
            if (this.log.IsErrorEnabled)
                this.log.Error("[" + DateTime.Now.ToString() + "] " + ExtractInfo(message), e);
        }
        public void Error(string message)
        {
            if (this.log.IsErrorEnabled)
                this.log.Error("[" + DateTime.Now.ToString() + "] " + ExtractInfo(message));
        }
        private string ExtractInfo(string message)
        {
            StackFrame frame1 = new StackFrame(2, true);
            string methodName = frame1.GetMethod().ToString();
            string fileName = Path.GetFileName(frame1.GetFileName());
            string[] textArray1 = new string[6] { "File:", fileName, " - Method:", methodName, " - ", message };
            return string.Concat(textArray1);
        }

    }


}